home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Development Kits / MPW etc / MPW-GM / MPW / Examples / HyperXExamples / CExamples / LittleDialog.c next >
Encoding:
C/C++ Source or Header  |  1998-12-03  |  5.4 KB  |  211 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     © 1988 by Apple Computer, Inc.
  4.     All Rights Reserved
  5.  
  6.     LittleDialog -- a Hypercard XCMD that displays a modal dialog. This example uses
  7.     callbacks to HyperCard provided by the HyperXLib.o library, introduced with MPW 3.0.
  8.     The library provides a consistent set of routines to call HyperCard internal routines
  9.     from any language. This is the first public demonstration of its use.
  10.  
  11.     
  12.     Form: LittleDialog DisplayText
  13.     
  14.     Example: LittleDialog "Display this very long text string that wouldn't fit in Answer."
  15.     
  16.     DisplayText: The text to display in the window. Up to 255 characters may be displayed.
  17.     
  18.  
  19.     To compile and link this file using MPW C, select the following lines and
  20.     press ENTER:
  21.     
  22.     make LittleDialog
  23.     
  24.     or:
  25.     
  26.     C -b LittleDialog.c -mbg off
  27.     Link -w -rt XCMD=10002 ∂
  28.         -m ENTRYPOINT ∂
  29.         -sg LittleDialog ∂
  30.         LittleDialog.c.o ∂
  31.         "{Libraries}HyperXLib.o" ∂
  32.         "{Libraries}Interface.o" ∂
  33.         "{CLibraries}StdCLib.o" ∂
  34.         "{Libraries}Runtime.o" ∂
  35.         -o "::HyperXExample Stack"
  36.     Rez LittleDialog.r -o "::HyperXExample Stack" -append
  37.     
  38. */
  39.  
  40. #include <Types.h>
  41. #include <Dialogs.h>
  42. #include <Memory.h>
  43. #include <Events.h>
  44. #include <QuickDraw.h>
  45. #include <Resources.h>
  46. #include <HyperXCmd.h>
  47. #include <String.h>    // for definition of strlen()
  48.  
  49. #define    dialogID    (short) 10002
  50. #define DLOG            (long)    0x444C4F47
  51. #define DITL            (long)    0x4449544C        
  52. #define    gap                (int)        -4
  53. #define    defaultOK    (short) 2
  54.  
  55. static void ErrAbort(XCmdPtr paramPtr, char *str);
  56. pascal void DrawOKDefault(DialogPtr theDialog, short theItem);
  57.  
  58. pascal void EntryPoint(XCmdPtr paramPtr)
  59. {
  60.  
  61.     GrafPtr            savePort;
  62.     Str255            displayStr;
  63.     DialogPtr        myDialogPtr;
  64.     Rect                itemRect;
  65.     short                itemType;
  66.     Handle            item;
  67.     short                itemHit;
  68.     
  69.     /*
  70.         Save the current port; good defensive programming practice.
  71.         NOTE: this port will always be the card window's grafport.
  72.     */
  73.     GetPort(&savePort);
  74.                                                 
  75.     /*    
  76.         It is always a good idea to check for the correct number of parameters.
  77.         Another nice idea is to return the proper syntax of the call if it has
  78.         been called improperly.
  79.     */
  80.     if(paramPtr->paramCount != 1)
  81.         {
  82.             ErrAbort(paramPtr,"Correct usage is: 'LittleDialog fieldName'");
  83.             return;
  84.         }
  85.         
  86.     /*        
  87.         This routine will use DLOG and DITL resources that must be available.
  88.         Since XCMDs may be moved by ResEdit without knowledge of those resources,
  89.         we must check for their availability. To suggest that our DLOG, DITL, and
  90.         XCMD all belong together, we have numbered them all the same: 10002.
  91.     */
  92.     if((GetResource((ResType)DLOG,dialogID) == nil) ||
  93.         (GetResource((ResType)DITL,dialogID) == nil))
  94.         {
  95.             ErrAbort(paramPtr,"XCMD requires resources: DLOG 10002 & DITL 10002.");
  96.             return;
  97.         }
  98.  
  99.     /*
  100.         Convert the zero-terminated string that was the parameter to the XCMD
  101.         into a pascal string.  Set it up to be the string that will be displayed.
  102.         DLOG 10002 is already set up to display a text string.
  103.     */
  104.     HLock(paramPtr->params[0]);
  105.     ZeroToPas(paramPtr,*(paramPtr->params[0]),displayStr); 
  106.     HUnlock(paramPtr->params[0]);
  107.     ParamText(displayStr, (ConstStr255Param) "", (ConstStr255Param) "", (ConstStr255Param) ""); 
  108.     SetDialogFont(0);                                        /* possibly redundant, but safe nonetheless */
  109.  
  110.     /*
  111.         Get a pointer to the not yet visible dialog.
  112.         Abort with error message if lacking memory.
  113.     */
  114.     myDialogPtr = GetNewDialog(dialogID,nil,(WindowPtr)-1);
  115.     if (myDialogPtr == nil) 
  116.         {
  117.             ErrAbort(paramPtr,"Not enough memory for dialog.");
  118.             return;
  119.         }
  120.         
  121.     /*
  122.         Get the rect of the OK button and enlarge it slightly.
  123.         Use it to surround user item #2 to make a default (ringed) button.
  124.         The function DrawOKDefault will draw the button.
  125.     */
  126.     GetDialogItem(myDialogPtr,ok,&itemType,&item,&itemRect); 
  127.     InsetRect(&itemRect,gap,gap);                             
  128.     SetDialogItem(myDialogPtr,defaultOK,(userItem | itemDisable),(Handle)&DrawOKDefault,&itemRect);
  129.         
  130.     /* Make the dialog visible. */
  131.     
  132.     ShowWindow(myDialogPtr);
  133.  
  134.     /* Set the cursor to the arrow for use with the dialog box. */
  135.         
  136.     InitCursor();
  137.     
  138.     /* Flush all events to be safe. */        
  139.  
  140.     FlushEvents(everyEvent,0); 
  141.     
  142.     /*
  143.         Make the modal dialog handle events.
  144.         Display the dialog until the user clicks OK.
  145.         Then get rid of dialog and dialog handle.
  146.         And restore the port.
  147.     */
  148.     do
  149.         {
  150.             ModalDialog(nil,&itemHit);
  151.         }
  152.     while (itemHit != ok);
  153.  
  154.         /*
  155.             Let HyperCard set the cursor to a known state, so the next "idle" message
  156.             after the dialog goes away will reset it to the correct cursor. (HyperCard
  157.             doesn't know we did an InitCursor.)
  158.         */
  159.             
  160.     SendHCMessage(paramPtr,"\pset cursor to 4");    /* 4 = the watch cursor */
  161.                                                     /* string must be a Pascal string */
  162.  
  163.     /*
  164.         Then get rid of dialog and dialog handle.
  165.         And restore the port.
  166.     */
  167.     DisposeDialog(myDialogPtr);     
  168.     SetPort(savePort);                 
  169.     
  170. }
  171.  
  172.  
  173. static void ErrAbort(XCmdPtr paramPtr, char *str)
  174. {
  175.     Handle  nuHndl;
  176.  
  177.     /*
  178.         Allocate space for an error message.
  179.         Copy the string into it.
  180.         Return the handle to HyperCard.
  181.     */
  182.     nuHndl = NewHandle((long)(strlen(str)+1));
  183.     if (nuHndl == nil) return;
  184.     strcpy((char *)*nuHndl,str);
  185.     paramPtr->returnValue = nuHndl;
  186. }
  187.  
  188.  
  189. #define curveRad    (short) 16
  190. #define    nuPenSize    (short) 3
  191.  
  192. pascal void DrawOKDefault(DialogPtr theDialog, short theItem)
  193. {
  194.     PenState    savePen;
  195.     short            itemType;
  196.     Handle        item;
  197.     Rect            itemRect;
  198.     
  199.     /*
  200.         Save the pen state.
  201.         Draw an outline with a larger pen around our default OK button.
  202.         Then restore the pen state.
  203.     */
  204.     GetPenState(&savePen);
  205.     GetDialogItem(theDialog,theItem,&itemType,&item,&itemRect);
  206.     PenSize(nuPenSize,nuPenSize);
  207.     FrameRoundRect(&itemRect,curveRad,curveRad);
  208.     SetPenState(&savePen);
  209. }
  210.  
  211.